home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <Memory.h>
- #include <Errors.h>
- #include <strings.h>
-
- /************************************************************************
- *
- * © Copyright 1988, 1990, 1994 Apple Computer, Inc. All rights reserved.
- *
- * Program: BuildISO
- *
- * Purpose: build an ISO 9660 floppy
- *
- * Description: Try to build a ISO 9660 floppy disc, interactively.
- * Currently only builds the Primary Volume Descriptor
- * and puts files at the root level. Does not do
- * subdirectories.
- *
- * Revision History:
- * 1 July 88 Original Version for the Macintosh by Brian Bechtel,
- * Apple Computer, Inc.
- * April 90 Modified for d e v e l o p and Think C 4.0
- * January 94 Converted to Universal Headers. Fixed a bug reported
- * by Hans-Martin Mosner (hmm@heeg.de) which prevented
- * Apple extensions from working correctly.
- *
- ************************************************************************/
-
- #include "HighSierra.h"
- #include "BuildISO.h"
-
- #define FLOPPY_SIZE 0x186 /* size in 2k blocks of a 800k floppy */
-
- #include "BuildISO.proto.h"
- #include "ErrorMsg.proto.h"
- #include "i_o.proto.h"
- #include "Support.proto.h"
- #include "MyDialog.proto.h"
-
- Str255 nullStr = "\p";
- Str255 rootName = "\p\000";
- Str255 parentName = "\p\001";
-
- /************************************************************************
- *
- * Function: CreatePVD
- *
- * Purpose: create the contents of the Primary Volume Descriptor.
- *
- * Returns: void
- *
- * Side Effects: adds to the output file.
- *
- * Description: go through all the primary volume descriptor, showing
- * each field in all it's glory. We don't bother showing
- * the extra blanks at the end of each string field.
- *
- *
- ************************************************************************/
-
- OSErr
- CreatePVD(short referenceNumber)
- {
- PVD p;
- OSErr result;
- long offset;
- char volID[33];
- Boolean goOn;
-
- ClearOut((char *)&p, sizeof(p));
- p.VDType = 1;
- p.VSStdId[0] = 'C';
- p.VSStdId[1] = 'D';
- p.VSStdId[2] = '0';
- p.VSStdId[3] = '0';
- p.VSStdId[4] = '1';
- p.VSStdVersion = 1;
- CharCopy(p.systemIdentifier, "Apple Computer, Inc., Type:0001", sizeof(p.systemIdentifier));
-
- goOn = AskForString((char *)"\pWhat do you want to call this volume? (32 characters or less)", volID);
- if (goOn == false)
- return -1;
-
- NormalizeVolumeName(volID);
- CharCopy(p.volumeIdentifier, volID, sizeof(p.volumeIdentifier));
-
-
- p.lsbVolumeSpaceSize = NormalizeLong((long)FLOPPY_SIZE);
- p.msbVolumeSpaceSize = (long)FLOPPY_SIZE;
- p.lsbVolumeSetSize = NormalizeWord(FLOPPY_SIZE);
- p.msbVolumeSetSize = FLOPPY_SIZE;
- p.lsbVolumeSetSequenceNumber = NormalizeWord(1);
- p.msbVolumeSetSequenceNumber = 1;
-
- p.lsbLogicalBlockSize = NormalizeWord(CDBLKSIZE);
- p.msbLogicalBlockSize = CDBLKSIZE;
-
-
- p.lsbPathTableSize = NormalizeLong(PATHTBLSIZE);
- p.msbPathTableSize = PATHTBLSIZE;
- p.lsbPathTable1 = NormalizeLong(LSBPATH);
- p.msbPathTable1 = MSBPATH;
-
- p.lsbPathTable2 = 0L;
- p.msbPathTable2 = 0L;
-
- /* Exercise for reader: get the time via GetTime() and convert
- ** to string of the format shown below for these strange dates.
- ** Use that date and time to fill the various volume date fields.
- ** The date shown is my daughter's birth date and time...
- */
- CharCopy(p.volumeCreation, "19870914060100000", sizeof(p.volumeCreation));
- CharCopy(p.volumeModification, "19870914060100000", sizeof(p.volumeModification));
- CharCopy(p.volumeExpiration, "00000000000000000", sizeof(p.volumeExpiration));
- CharCopy(p.volumeEffective, "19870914060100000", sizeof(p.volumeEffective));
-
- p.FileStructureStandardVersion = 1;
-
- SpaceOut(p.volumeSetIdentifier, sizeof(p.volumeSetIdentifier));
- SpaceOut(p.publisherIdentifier, sizeof(p.publisherIdentifier));
- SpaceOut(p.dataPreparerIdentifier, sizeof(p.dataPreparerIdentifier));
- SpaceOut(p.applicationIdentifier, sizeof(p.applicationIdentifier));
- SpaceOut(p.copyrightFileIdentifier, sizeof(p.copyrightFileIdentifier));
- SpaceOut(p.abstractFileIdentifier, sizeof(p.abstractFileIdentifier));
- SpaceOut(p.bibliographicFileIdentifier, sizeof(p.bibliographicFileIdentifier));
-
- CreateDirRcd((DirRcd *)&p.rootDirectoryRecord, rootName,
- DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
-
- p.Reserved1 = 0;
- ClearOut(p.Reserved2, sizeof(p.Reserved2));
- ClearOut(p.Reserved3, sizeof(p.Reserved3));
- p.Reserved4 = 0;
-
- #ifdef VERBOSE /* if I want to verify what I've done */
- DumpPVD(&p);
- #endif
- offset = (long) HSVOLSTART * (long) CDBLKSIZE;
- result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
- if (result != noErr)
- ErrorMsg("CreatePVD: isoWrite() returned %d", result);
- else
- ErrorMsg("volume descriptors successfully created.");
- return result;
- }
-
-
- /************************************************************************
- *
- * Function: CreateVDT
- *
- * Purpose: create the contents of the Volume Descriptor Terminator
- *
- * Returns: void
- *
- * Side Effects: adds to the output file.
- *
- * Description: Build a simple VDT, fill it in, and write it out to
- * a famous place.
- *
- *
- ************************************************************************/
-
- OSErr
- CreateVDT(short referenceNumber)
- {
- PVD p;
- OSErr result;
- long offset;
-
- ClearOut((char *)&p, sizeof(p));
- p.VDType = 255;
- p.VSStdId[0] = 'C';
- p.VSStdId[1] = 'D';
- p.VSStdId[2] = '0';
- p.VSStdId[3] = '0';
- p.VSStdId[4] = '1';
- p.VSStdVersion = 1;
- offset = (long) HSTERMSTART * (long) CDBLKSIZE;
- result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
- if (result != noErr)
- ErrorMsg("CreateVDT: isoWrite() returned %d", result);
- return result;
- }
-
-
-
-
- /************************************************************************
- *
- * Function: CreatePathTable
- *
- * Purpose: create path tables
- *
- * Returns: nothing
- *
- * Side Effects: writes lsb path table and msb path table
- *
- * Description: We'll assume just the root. Dump out the path
- * path table in both formats. We'll put the
- * path table in famous spots.
- *
- ************************************************************************/
- OSErr
- CreatePathTable(short referenceNumber)
- {
- char buffer[CDBLKSIZE];
- PathTableRecordPtr d;
- long offset;
- OSErr result;
-
- ClearOut(buffer, sizeof(buffer));
- d = (PathTableRecordPtr) &buffer[0];
-
- d->len_di = 1;
- d->XARlength = 0;
- d->dirLocation = NormalizeLong(DIRECTORY);
- d->parentDN = 0;
-
- offset = LSBPATH * (long) CDBLKSIZE;
- result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
- if (result != noErr)
- ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
-
- d->len_di = 1;
- d->dirLocation = DIRECTORY;
- d->parentDN = 0;
-
- offset = MSBPATH * (long) CDBLKSIZE;
- result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
- if (result != noErr)
- ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
- return result;
- }
-
-
- /************************************************************************
- *
- * Function: CreateDirRcd
- *
- * Purpose: Create a directory record for a file
- *
- * Returns: none
- *
- * Side Effects: fills *d with directory information. We assume
- * caller has allocated space for d.
- *
- * Description:
- *
- ************************************************************************/
- void
- CreateDirRcd(DirRcd *d, StringPtr name, long start, long length, short flags, OSType fType, OSType fCreator, short finderFlags)
- {
- Ptr dPtr;
- DateTimeRec today;
-
- d->XARlength = 0;
- d->lsbStart = NormalizeLong(start);
- d->msbStart = start;
- d->lsbDataLength = NormalizeLong(length);
- d->msbDataLength = length;
- d->fileFlags = flags;
- if (finderFlags & fInvisible)
- d->fileFlags |= existenceBit;
- GetTime(&today);
- d->year = today.year-1900;
- d->month = today.month;
- d->day = today.day;
- d->hour = today.hour;
- d->minute = today.minute;
- d->second = today.second;
- d->gmtOffset = 0;
- d->interleaveSize = 0;
- d->interleaveSkip = 0;
- d->lsbVolSetSeqNum = NormalizeWord(1);
- d->msbVolSetSeqNum = 1;
-
- d->len_fi = CreateISOName((char *)d->fi, name);
-
- d->len_dr = 32 + d->len_fi;
-
- AddAppleExtensions(d, fType, fCreator, finderFlags);
-
- if (d->len_dr & 1) /* odd dirRcds need pad byte */
- {
- dPtr = (char *)d;
- dPtr[d->len_dr] = '\000';
- d->len_dr++;
- }
- }
-
-
- /************************************************************************
- *
- * Function: AddOldAppleExtensions
- *
- * Purpose: optionally add apple extensions to ISO 9660
- *
- * Returns: void
- *
- * Side Effects: directory record may get extended. Must have enough
- * room in area pointed to by dirRcd for this to happen.
- *
- * Description: Check the fType. If it's non-zero, add the information
- * necessary for the Apple Extensions to ISO 9660. Note
- * that we can't just assign fType and fCreator, since
- * longs are aligned within structures.
- *
- * This procedure adds the old, "BA" Apple extensions.
- *
- ************************************************************************/
- void
- AddOldAppleExtensions(DirRcd *dirRcd, OSType fType, OSType fCreator, short flags)
- {
- OldAppleExtension apple;
- short i;
- short j;
- short limit;
- char *aPtr;
- Ptr fPtr;
-
- if (fType != 0L)
- {
- apple.macFlag[0] = 'B';
- apple.macFlag[1] = 'A';
- apple.systemUseID = 06;
- fPtr = (char *)&fType;
-
- for (i = 0; i < 4; i++)
- apple.fileType[i] = fPtr[i];
- fPtr = (char *)&fCreator;
-
- for (i = 0; i < 4; i++)
- apple.fileCreator[i] = fPtr[i];
-
- apple.finderFlags[0] = (flags >> 8) & 0xFF;
- apple.finderFlags[1] = flags & 0xFF;
-
- limit = sizeof(apple);
-
- aPtr = (char *)&apple;
-
- j = dirRcd->len_fi;
-
- if (!(j & 1)) /* 9401 bug fix BL°B */
- {
- dirRcd->fi[j] = 0;
- j++; /* there is a pad byte after odd length file names */
- }
-
- for (i = 0; i <= limit; i++)
- dirRcd->fi[i + j] = aPtr[i];
-
- dirRcd->len_dr += limit;
- }
- }
-
-
- /************************************************************************
- *
- * Function: AddAppleExtensions
- *
- * Purpose: optionally add apple extensions to ISO 9660
- *
- * Returns: void
- *
- * Side Effects: directory record may get extended. Must have enough
- * room in area pointed to by dirRcd for this to happen.
- *
- * Description: Check the fType. If it's non-zero, add the information
- * necessary for the Apple Extensions to ISO 9660. Note
- * that we can't just assign fType and fCreator, since
- * longs are aligned within structures.
- *
- ************************************************************************/
- void
- AddAppleExtensions(DirRcd *dirRcd, OSType fType, OSType fCreator, short flags)
- {
- AppleExtension apple;
- short i;
- short j;
- short limit;
- char *aPtr;
- Ptr fPtr;
-
- if (fType != 0L)
- {
- apple.signature[0] = 'A';
- apple.signature[1] = 'A';
- apple.extensionLength = 0x0E;
- apple.systemUseID = 02;
- fPtr = (char *)&fType;
-
- for (i = 0; i < 4; i++)
- apple.fileType[i] = fPtr[i];
- fPtr = (char *)&fCreator;
-
- for (i = 0; i < 4; i++)
- apple.fileCreator[i] = fPtr[i];
-
- apple.finderFlags[0] = (flags >> 8) & 0xFF;
- apple.finderFlags[1] = flags & 0xFF;
-
- limit = sizeof(apple);
-
- aPtr = (char *)&apple;
-
- j = dirRcd->len_fi;
-
- if (!(j & 1)) /* 9401 bug fix BL°B */
- {
- dirRcd->fi[j] = 0;
- j++; /* there is a pad byte after odd length file names */
- }
-
- for (i = 0; i <= limit; i++)
- dirRcd->fi[i + j] = aPtr[i];
-
- dirRcd->len_dr += limit;
- }
- }
-
-
- /************************************************************************
- *
- * Function: CopyDirRcdToBuffer
- *
- * Purpose: copy directory record to buffer
- *
- * Returns: nothing
- *
- * Side Effects: buffer is filled a little bit more
- *
- * Description: copy a directory record to the buffer.
- *
- ************************************************************************/
- void
- CopyDirRcdToBuffer(DirRcd *d, char *b)
- {
- char *dPrime;
- short i;
-
- dPrime = (char *)d;
- for (i = 0; i < d->len_dr; i++)
- *b++ = *dPrime++;
- }
-
- /************************************************************************
- *
- * Function: CopyRsrcFork
- *
- * Purpose: copy the resource fork of a file
- *
- * Returns: OSErr
- * mostly noErr, but could be
- * ioErr and the like if isoWrite complains.
- *
- * Side Effects: floppy gets new data written on it.
- *
- * Description: we have a starting location, "start", and a length.
- * Allocate an appropriate buffer and read from the file
- * specified by "name" and "vRefNum". Write that information
- * out to the floppy using our isoWrite call.
- *
- ************************************************************************/
- OSErr
- CopyRsrcFork(short referenceNumber, StringPtr name, short vRefNum, long start, long length) /* how much to write */
- {
- Ptr rsrcBuf;
- ParamBlockRec pb;
- Boolean goOn;
- OSErr result;
- long physicalLength;
- short myRefNum;
-
- ClearOut((Ptr)&pb, sizeof(pb));
- goOn = true;
- physicalLength = ROUND_UP(length);
-
- rsrcBuf = NewPtrClear(physicalLength);
- if (rsrcBuf == NULL)
- {
- ErrorMsg("Can't allocate %ld bytes for CopyRsrcFork()", length);
- return mFulErr; /* nothing to clean up */
- }
-
- pb.ioParam.ioCompletion = NULL;
- pb.ioParam.ioNamePtr = name;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioVersNum = 0;
- pb.ioParam.ioPermssn = fsCurPerm;
- pb.ioParam.ioMisc = NULL;
- result = PBOpenRF(&pb, false);
- if (result != noErr)
- {
- ErrorMsg("CopyRsrcFork: PBOpenRF returned %d", result);
- ErrorMsg("vRefNum %d, name %P", vRefNum, name);
- C2PStr((char *)name);
- goOn = false;
- }
-
- if (goOn)
- {
- myRefNum = pb.ioParam.ioRefNum;
- result = FSRead(myRefNum, &length, rsrcBuf);
- if (result != noErr)
- {
- ErrorMsg("CopyRsrcFork: FSRead returned %d", result);
- goOn = false;
- }
- }
-
- if (goOn)
- {
- result = isoWrite(referenceNumber, rsrcBuf, physicalLength, start);
-
- if (result != noErr)
- {
- ErrorMsg("CopyRsrcFork: isoWrite returned %d", result);
- goOn = false;
- }
- }
-
- PBClose(&pb, false);
- DisposPtr(rsrcBuf);
- return result;
- }
-
-
-
- /************************************************************************
- *
- * Function: CopyDataFork
- *
- * Purpose: copy the resource fork of a file
- *
- * Returns: OSErr
- * mostly noErr, but could be
- * ioErr and the like if isoWrite complains.
- *
- * Side Effects: floppy gets new data written on it.
- *
- * Description: we have a starting location, "start", and a length.
- * Allocate an appropriate buffer and read from the file
- * specified by "name" and "vRefNum". Write that information
- * out to the floppy using our isoWrite call.
- *
- ************************************************************************/
- OSErr
- CopyDataFork(short referenceNumber, StringPtr name, short vRefNum, long start, long length) /* how much to write */
- {
- Ptr dataBuf;
- ParamBlockRec pb;
- Boolean goOn;
- OSErr result;
- long physicalLength;
- short myRefNum;
-
- ClearOut((Ptr)&pb, sizeof(pb));
- goOn = true;
- physicalLength = ROUND_UP(length);
-
- dataBuf = NewPtrClear(physicalLength);
- if (dataBuf == NULL)
- {
- ErrorMsg("Can't allocate %ld bytes for CopyDataFork()", length);
- return mFulErr; /* nothing to clean up */
- }
-
- pb.ioParam.ioCompletion = NULL;
- pb.ioParam.ioNamePtr = name;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioVersNum = 0;
- pb.ioParam.ioPermssn = fsCurPerm;
- pb.ioParam.ioMisc = NULL;
- result = PBOpen(&pb, false);
- if (result != noErr)
- {
- ErrorMsg("CopyDataFork: PBOpen returned %d", result);
- ErrorMsg("vRefNum %d, name %P", vRefNum, name);
- C2PStr((char *)name);
- goOn = false;
- }
-
- if (goOn)
- {
- myRefNum = pb.ioParam.ioRefNum;
- result = FSRead(myRefNum, &length, dataBuf);
- if (result != noErr)
- {
- ErrorMsg("CopyDataFork: FSRead returned %d", result);
- goOn = false;
- }
- }
-
- if (goOn)
- {
- result = isoWrite(referenceNumber, dataBuf, physicalLength, start);
-
- if (result != noErr)
- {
- ErrorMsg("CopyDataFork: isoWrite returned %d", result);
- goOn = false;
- }
- }
-
- PBClose(&pb, false);
- DisposPtr(dataBuf);
- return result;
- }
-
- /************************************************************************
- *
- * Function: CreateFiles
- *
- * Purpose: create files in the root of a ISO floppy.
- *
- * Returns: nothing
- *
- * Side Effects: floppy gets new data in famous root area
- *
- * Description: For each file, find the size of the two forks.
- * Copy the resource fork first, then the data fork
- * (associated files come before data files in ISO)
- *
- ************************************************************************/
- void
- CreateFiles(short referenceNumber)
- {
- StringPtr name;
- short vRefNum;
- DirRcd dirRcd;
- long start; /* where we start putting data on the CD */
- long rsrcLength;
- long dataLength;
- char *b;
- OSErr result;
- OSType fType;
- OSType fCreator;
- short flags;
- short ISOFlags;
- char buffer[CDBLKSIZE];
-
-
- ClearOut(buffer, sizeof(buffer));
- b = &buffer[0];
- name = (StringPtr)NewPtr(255);
- if (name == NULL)
- {
- ErrorMsg("Can't allocate 255 bytes for a string.");
- return;
- }
-
- CreateDirRcd(&dirRcd, rootName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
- CopyDirRcdToBuffer(&dirRcd, b);
- b += dirRcd.len_dr;
-
- CreateDirRcd(&dirRcd, parentName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
- CopyDirRcdToBuffer(&dirRcd, b);
- b += dirRcd.len_dr;
-
- start = DATASTART * CDBLKSIZE;
-
- /* Keep asking for names, even if errors occur. Most errors will be because
- * The user tried to copy too big of a file to the floppy.
- */
- while (HFSFile(name, &vRefNum) == true)
- {
- result = GetFileInfo(name, vRefNum, &rsrcLength, &dataLength, &fType, &fCreator, &flags);
- if (result != noErr)
- ErrorMsg("Can't get file information for %s", name);
- else
- {
- ISOFlags = (flags & fInvisible) ? existenceBit : 0;
-
- if (rsrcLength != 0L)
- {
- CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, rsrcLength, ISOFlags | associatedBit,
- fType, fCreator, flags);
-
- result = CopyRsrcFork(referenceNumber, name, vRefNum, start, rsrcLength);
- if (result == noErr)
- {
- CopyDirRcdToBuffer(&dirRcd, b);
- b += dirRcd.len_dr;
- start = ROUND_UP(start+rsrcLength);
- }
- else
- ErrorMsg("Failed to copy resource fork.");
-
- }
-
- if (result == noErr)
- {
- CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, dataLength, ISOFlags,
- fType, fCreator, flags);
-
- result = CopyDataFork(referenceNumber, name, vRefNum, start, dataLength);
- if (result == noErr)
- {
- CopyDirRcdToBuffer(&dirRcd, b);
- b += dirRcd.len_dr;
- start = ROUND_UP(start+dataLength);
- }
- else
- ErrorMsg("Failed to copy data fork.");
-
- ClearOut((Ptr)name, 255);
- }
- }
- }
-
- result = isoWrite(referenceNumber, (Ptr)buffer, (long)sizeof(buffer), (long) (DIRECTORY*CDBLKSIZE));
- if (result != noErr)
- ErrorMsg("CreateDataFiles: isoWrite of directory records returned %d", result);
- DisposPtr((Ptr)name);
- }
-
-